#!/usr/bin/env python3
"""
Zabbix告警分析汇报脚本 - 主入口文件
支持PostgreSQL和MySQL数据库，模块化架构设计

最低Python版本要求: 3.7+

使用方法:
    python main.py              # 执行完整的告警分析和推送
    python main.py --dry-run    # 仅分析告警，不发送通知
    python main.py --test-db    # 测试数据库连接
"""

import sys
import argparse
from typing import Optional, Tuple, Dict

# Python版本检查
if sys.version_info < (3, 7):
    print("❌ 错误: 需要 Python 3.7 或更高版本")
    print(f"当前版本: Python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
    sys.exit(1)

# 导入自定义模块
from config import Config
from database import ZabbixDatabase
from analyzer import AlertAnalyzer
from notification import NotificationSender
from utils import LogUtils

def parse_arguments():
    """解析命令行参数"""
    parser = argparse.ArgumentParser(description='Zabbix告警分析汇报脚本')
    parser.add_argument('--dry-run', action='store_true', 
                       help='仅分析告警，不发送通知')
    parser.add_argument('--test-db', action='store_true',
                       help='测试数据库连接')
    parser.add_argument('--verbose', '-v', action='store_true',
                       help='显示详细日志')
    
    return parser.parse_args()

def test_database_connection() -> bool:
    """测试数据库连接"""
    LogUtils.log_operation_start("数据库连接测试")
    
    db = ZabbixDatabase()
    try:
        db.connect()
        LogUtils.log_operation_success("数据库连接测试", f"连接类型: {db.db_type}")
        return True
    except Exception as e:
        LogUtils.log_operation_error("数据库连接测试", str(e))
        return False
    finally:
        db.disconnect()

def run_alert_analysis(dry_run: bool = False) -> Tuple[bool, Dict]:
    """执行告警分析 - 返回执行结果和统计信息"""
    from datetime import datetime
    start_time = datetime.now()
    
    LogUtils.log_operation_start("Zabbix告警分析汇报")
    
    # 验证配置
    if not Config.validate():
        LogUtils.log_operation_error("配置验证", "必要配置项缺失")
        execution_time = (datetime.now() - start_time).total_seconds()
        return False, {
            'alert_count': 0,
            'execution_time': execution_time,
            'notification_sent': False,
            'error': '必要配置项缺失'
        }
    
    # 初始化组件
    db = ZabbixDatabase()
    analyzer = AlertAnalyzer()
    notification_sender: Optional[NotificationSender] = None
    
    if not dry_run:
        notification_sender = NotificationSender(db.db_type)
    
    try:
        # 连接数据库
        LogUtils.log_operation_start("连接数据库")
        db.connect()
        LogUtils.log_operation_success("连接数据库", f"类型: {db.db_type}")
        
        # 获取当前告警
        LogUtils.log_operation_start("获取告警数据")
        alerts = db.get_current_alerts()
        LogUtils.log_database_stats(db.db_type, len(alerts))
        
        # 分析告警
        LogUtils.log_operation_start("分析告警数据")
        analysis_report, deepseek_success = analyzer.analyze_alerts(alerts)
        LogUtils.log_operation_success("分析告警数据")
        
        # 如果 DeepSeek 失败且不是 dry-run 模式，发送警告通知
        if not deepseek_success and not dry_run and notification_sender:
            warning_msg = f"⚠️ **DeepSeek AI 分析服务不可用**\n\n已自动切换到内置分析引擎，报告结果仍然有效。\n\n请检查 DeepSeek API 配置和网络连接。"
            try:
                notification_sender.send_alert_report("⚠️ DeepSeek API 警告", warning_msg)
                LogUtils.log_operation_success("DeepSeek失败通知", "已发送警告通知")
            except Exception:
                LogUtils.log_operation_error("DeepSeek失败通知", "发送失败")
        
        if dry_run:
            # 仅显示分析结果，不发送通知
            print("\n" + "="*60)
            print("告警分析结果 (DRY RUN模式)")
            print("="*60)
            print(analysis_report)
            print("="*60)
            LogUtils.log_operation_success("告警分析", "DRY RUN模式完成")
            execution_time = (datetime.now() - start_time).total_seconds()
            return True, {
                'alert_count': len(alerts),
                'execution_time': execution_time,
                'notification_sent': False
            }
        
        # 发送报告
        LogUtils.log_operation_start("发送告警报告")
        title = "🚨 Zabbix告警分析报告" if alerts else "✅ Zabbix系统状态正常"
        
        if notification_sender and notification_sender.send_alert_report(title, analysis_report):
            LogUtils.log_operation_success("发送告警报告")
            notification_sent = True
        else:
            LogUtils.log_operation_error("发送告警报告", "推送失败")
            notification_sent = False
        
        # 计算执行时间和返回统计信息
        execution_time = (datetime.now() - start_time).total_seconds()
        return notification_sent, {
            'alert_count': len(alerts),
            'execution_time': execution_time,
            'notification_sent': notification_sent
        }
            
    except Exception as e:
        error_msg = f"执行过程中发生错误: {e}"
        LogUtils.log_operation_error("告警分析汇报", str(e))
        
        # 尝试发送错误通知
        if not dry_run and notification_sender:
            try:
                notification_sender.send_error_notification(error_msg)
            except Exception:
                pass  # 忽略通知发送失败
        
        execution_time = (datetime.now() - start_time).total_seconds()
        return False, {
            'alert_count': 0,
            'execution_time': execution_time,
            'notification_sent': False,
            'error': str(e)
        }
    finally:
        db.disconnect()

def main():
    """主函数"""
    args = parse_arguments()
    
    # 设置日志级别
    if args.verbose:
        import logging
        logging.getLogger().setLevel(logging.DEBUG)
    
    success = True
    
    # 测试数据库连接
    if args.test_db:
        success = test_database_connection()
        if not success:
            sys.exit(1)
        return
    
    # 执行告警分析
    success, stats = run_alert_analysis(dry_run=args.dry_run)
    
    # 退出程序
    if success:
        LogUtils.log_task_completion("Zabbix告警分析汇报")
        # 打印执行统计信息（参考Prometheus格式）
        print("✅ 执行成功")
        print(f"   告警数量: {stats['alert_count']}")
        print(f"   执行时间: {stats['execution_time']:.2f}秒")
        if stats['notification_sent']:
            print("   📤 已发送通知")
        sys.exit(0)
    else:
        LogUtils.log_operation_error("Zabbix告警分析汇报", "任务失败")
        # 打印执行统计信息（失败情况）
        print("❌ 执行失败")
        print(f"   告警数量: {stats['alert_count']}")
        print(f"   执行时间: {stats['execution_time']:.2f}秒")
        if 'error' in stats:
            print(f"   错误: {stats['error']}")
        sys.exit(1)

if __name__ == "__main__":
    main()